<?php

namespace app\common\model;

use think\Cache;
use think\Db;
use think\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\exception\DataNotFoundException;
use think\exception\HttpResponseException;
use think\Model;

/**
 * 试卷
 */
class Exampaper extends Model
{


    protected $name = 'exam_paper';


    /**试卷类表 */
    public function examPaperList($where, $user_id = 0)
    {
        $list = self::where(function ($query) use ($where) {
            if (isset($where['exam_cate_id']) && $where['exam_cate_id'] > 0) {
                $query->where('exam_cate_id', $where['exam_cate_id']);
            }
            $query->where('deletetime IS NULL');
        })
            ->field('id as exam_paper_id,title,start_time')
            ->paginate();
        $signup_status = Db::name('exam_user_signup')->where(['user_id' => $user_id])->value('status', '-1');
        foreach ($list as &$item) {
            $item->signup_status = $signup_status;
            if ($user_id > 0) {
                # 查询考试分数 和 排名
                $examusergrade =  Db::name('exam_user_grade')->where(['user_id' => $user_id, 'paper_id' => $item->exam_paper_id])->field('read,score')->find();
                $item->grade_read = !empty($examusergrade) ? $examusergrade['read'] : '-';
                $item->grade_score = !empty($examusergrade) ? $examusergrade['score'] : '-';
            } else {
                $item->grade_read = '-';
                $item->grade_score = '-';
            }
        }
        return $list;
    }


    /**
     * 考试页面
     */
    public function getExamIndex($exam_paper_id, $user_id = 0)
    {
        if (!$exam_paper_id) {
            fail("考试ID不能为空");
        }
        $exam_paper = self::where('id', $exam_paper_id)
            ->field('id as exam_paper_id,title,limit_time,total_score,start_time,end_time,describe')
            ->find();
        if (!$exam_paper) {
            fail("考试不存在");
        }
        $signup_status = Db::name('exam_user_signup')->where(['user_id' => $user_id])->value('status', '-1');
        $exam_paper->signup_status = $signup_status;

        // 获取考试状态
        $exam_paper->exam_status = $this->getExamStatus($exam_paper->start_time, $exam_paper->end_time);

        return $exam_paper;
    }


    /**
     * 获取试卷题目
     */
    public function getExamQuestion($exam_paper_id, $user_id)
    {
        if (!$exam_paper_id) {
            fail('缺少试卷ID');
        }
        # 验证试卷信息
        $paper = self::get($exam_paper_id);
        switch ($paper['mode']) {
            case "FIX":
                # 固定选题
                $questions = self::getFixQuestions($paper, $user_id);
                break;
            default:
                fail('试卷取题模式有误');
        }
        return [
            'paper'      => $paper, # 试卷信息
            'questions'  => $questions, # 题目信息
            'start_time' => time(),
        ];
    }

    /**
     * 固定选题
     * @param mixed $paper 
     * @param int $user_id 
     * @return mixed 
     * @throws HttpResponseException 
     */
    public function getFixQuestions($paper, $user_id = 0)
    {
        $questions = (new Question())->getFixListByExamPaper($paper['id'], $user_id);
        if (empty($questions)) fail('试卷题目信息不存在');
        return $questions;
    }


    /**
     * 提交试卷 
     * @param mixed $user_id  用户id
     * @param mixed $paper_id  试卷id
     * @param mixed $user_questions 用户提交答案
     * @param mixed $start_time 开始考时间
     * @param mixed &$paper 试卷信息
     */
    public static function paperExamSubmit($user_id, $paper_id, $user_questions, $start_time, &$paper)
    {
        if (!$questions_ids = array_column($user_questions, 'question_id')) {
            fail('提交的题目数据有误');
        }
        $paper = self::where('id', $paper_id)->find();
        # 用户答案
        $answers      = array_column($user_questions, 'answer');
        $total_score  = 0;                                              // 试卷总分
        $error_count  = 0;   // 错误题目数量
        $manual_score = 0;   // 主观题录得分                                      
        $error_ids    = [];
        //错误题目id
        $questions = (new Question())->getFixListByExamPaper($paper['id'], $user_id);
        if (count($user_questions) != count($questions)) {
            fail('提交题目数量有误');
        }

        foreach ($questions as $key => $question) {
            $score = $question['score'];
            switch ($question['kind']) {
                case 'JUDGE':   // 判断题
                case 'SINGLE':  // 单选题
                case 'MULTI':   // 多选题
                    // 答题正确
                    if (strtoupper($answers[$key]) == $question['answer']) {
                        $total_score                      += $score;
                        $user_questions[$key]['is_right'] = 1;
                    } else {
                        array_push($error_ids, $question['question_id']);
                        $error_count++;
                        $user_questions[$key]['is_right'] = $answers[$key] == '' ? -1 : 0;
                    }
                    break;
                case 'FILL':    // 填空题
                    $user_answers = $answers[$key];
                    // 确保用户答案是数组格式
                    if (!is_array($user_answers)) {
                        $user_answers = explode('|||', $user_answers);
                    }
                    $fill_right_count = 0;
                    $question['answer'] = is_array($question['answer']) ? $question['answer'] : json_decode($question['answer'], true);
                    // 处理填空题答案结构
                    $fill_answers = [];
                    if (isset($question['answer']['answers']) && is_array($question['answer']['answers'])) {
                        $fill_answers = $question['answer']['answers'];
                    } else {
                        // 兼容旧格式，直接使用answer字段
                        $fill_answers = $question['answer'];
                    }

                    // 遍历每个填空项
                    foreach ($fill_answers as $fill_key => $fill_answer_item) {
                        // 确保填空答案是数组格式
                        if (!is_array($fill_answer_item)) {
                            $fill_answer_item = [$fill_answer_item];
                        }

                        // 检查用户答案是否在正确答案列表中
                        if (isset($user_answers[$fill_key])) {
                            $user_answer = is_string($user_answers[$fill_key]) ? trim($user_answers[$fill_key]) : $user_answers[$fill_key];
                            foreach ($fill_answer_item as $correct_answer) {
                                $correct_answer_trimmed = is_string($correct_answer) ? trim($correct_answer) : $correct_answer;
                                # 使用in_array 判定
                                // if ($correct_answer_trimmed == $user_answer) {
                                if (in_array($user_answer, $correct_answer_trimmed)) {
                                    $fill_right_count++;
                                    break;
                                }
                            }
                        }
                    }
                    // 所有填空项全对
                    if ($fill_right_count == count($fill_answers)) {
                        $user_questions[$key]['is_right'] = 1;
                        $total_score += $score;
                    } else {
                        $user_questions[$key]['is_right'] = $answers[$key] == '' ? -1 : 0;;
                        array_push($error_ids, $question['question_id']);
                        $error_count++;
                    }
                    break;
                case 'SHORT':   // 主观题
                    # 主观题 填写图片 获取问题都是默认是正确 分数默认加上
                    if ((isset($user_questions[$key]['imgs']) && $user_questions[$key]['imgs']) || $answers[$key]) {
                        $user_questions[$key]['is_right'] = 1;
                        $manual_score += $score;
                    } else {
                        $user_questions[$key]['is_right'] = -1;
                        array_push($error_ids, $question['question_id']);
                        $error_count++;
                    }
                    // print_r($user_questions[$key]['imgs']);die;
                    // print_r($answers[$key]);die;
                    // $user_questions[$key]['is_right'] = 1;
                    break;
            }
        }
        $arr = [
            'total_score'  => $paper['total_score'], // 试卷总分
            'score'        => $total_score, // 考试分数
            'system_score' => $total_score, // 系统评分
            'manual_score' => $manual_score,
            'is_pass'      => $total_score >= $paper['pass_score'], // 是否及格
            'pass_score'   => $paper['pass_score'], // 及格分数
            'total_count'  => count($questions), // 题目数量
            'right_count'  => count($questions) - $error_count, // 答对数量
            'error_count'  => $error_count, // 答错数量
            'start_time'   => $start_time,  // 开始时间
            'error_ids'    => implode(',', $error_ids), // 错误题目id
            'question_ids' => implode(',', $questions_ids), //试题ID集合
            'user_answers' => json_encode($user_questions, JSON_UNESCAPED_UNICODE), // 用户答案集合
            'mode'         => $paper['mode'], // 试卷选题模式
        ];
        return $arr;
    }


    /**
     * 获取考试状态
     * @param int $start_time 开始时间（时间戳）
     * @param int $end_time 结束时间（时间戳）
     * @return array 返回考试状态信息
     */
    public function getExamStatus($start_time, $end_time)
    {
        $current_time = time();
        $status_info = [
            'status' => '', // 状态标识
            'status_text' => '', // 状态描述
            'can_exam' => '', // 是否可以考试
            'remaining_time' => 0, // 剩余时间（秒）
            'wait_time' => 0 // 等待时间（秒）
        ];
        // 如果开始时间为0，表示不限制开始时间
        if ($start_time == 0) {
            $start_time = 0;
        }
        // 如果结束时间为0，表示不限制结束时间
        if ($end_time == 0) {
            $end_time = 0;
        }
        // 判断考试状态
        if ($start_time > 0 && $current_time < $start_time) {
            // 考试未开始
            $status_info['status'] = 'not_started';
            $status_info['status_text'] = '考试未开始';
            $status_info['can_exam'] = false;
            $status_info['wait_time'] = $start_time - $current_time;
        } elseif ($end_time > 0 && $current_time > $end_time) {
            // 考试已结束
            $status_info['status'] = 'ended';
            $status_info['status_text'] = '考试已结束';
            $status_info['can_exam'] = false;
        } else {
            // 考试进行中
            $status_info['status'] = 'in_progress';
            $status_info['status_text'] = '考试进行中';
            $status_info['can_exam'] = true;
            // 计算剩余时间
            if ($end_time > 0) {
                $status_info['remaining_time'] = $end_time - $current_time;
            }
        }
        return $status_info;
    }
}
